﻿using System;
using System.Net;
using System.Threading.Tasks;
using Phorest.Voucher.Models;
using RestSharp;
using RestSharp.Deserializers;

namespace Phorest.Voucher
{
    public class VoucherApi : IVoucherApi
    {
        // ---------------------------------------------------------------------------------------------

        private readonly RestClient client;
        public IWebProxy Proxy
        {
            get
            {
                return client.Proxy;
            }
            set
            {
                client.Proxy = value;
            }
        }

        // ---------------------------------------------------------------------------------------------

        public VoucherApi(string baseUrl, string username, string password)
        {
            client = new RestClient
            {
                BaseUrl = baseUrl,
                Authenticator = new HttpBasicAuthenticator(String.Format(Configuration.UserNameFormat, username), password)
            };

            client.AddHandler(Configuration.VoucherContentType, new XmlDeserializer());
        }

        // ---------------------------------------------------------------------------------------------

        public VoucherResponse CreateVoucher(VoucherRequest voucherRequest)
        {
            return CreateVoucherAsync(voucherRequest).Result;
        }

        // ---------------------------------------------------------------------------------------------

        public Task<VoucherResponse> CreateVoucherAsync(VoucherRequest voucherRequest)
        {
            var tcs = new TaskCompletionSource<VoucherResponse>();

            var serial = GetNewSerialNumberAsync(voucherRequest.Branch).Result;

            var request = new RestRequest(string.Format(Configuration.PostVoucherUrlFormat, voucherRequest.Branch.BusinessId), Method.POST)
            {
                XmlSerializer = { ContentType = Configuration.VoucherContentType }
            };

            request.AddBody(new Models.Voucher(voucherRequest, serial));


            client.ExecuteAsync(request, (response) =>
                tcs.SetResult(new VoucherResponse
                {
                    Success = response.StatusCode == HttpStatusCode.Created,
                    SerialNumber = serial.Serial
                }));

            return tcs.Task;
        }

        // ---------------------------------------------------------------------------------------------

        private Task<SerialNumber> GetNewSerialNumberAsync(Branch branch)
        {
            var tcs = new TaskCompletionSource<SerialNumber>();

            var request = new RestRequest(string.Format(Configuration.GetSerialUrlFormat, branch.BusinessId, branch.BranchId), Method.GET);
            client.ExecuteAsync<SerialNumber>(request, (response) => tcs.SetResult(response != null ? response.Data : null));

            return tcs.Task;
        }

        // ---------------------------------------------------------------------------------------------
    }
}